#include "interprete.h"
#include "entrenador.h"

Interprete::Interprete()
{
	contadorNotas = 0;
	contadorCompas = 0;
}

Interprete::~Interprete()
{

}

void Interprete::setCompas(const Compas& compas)
{
	   // TODO: hacer que se puedan ejecutar varios compases
	this->compas = compas;
    metronomo.setPulsosPorCompas(compas.getNumeroPulsos());
}

void Interprete::inicio()
{	
	primeraNota();
	//procesarNota();
	metronomo.arrancar();
}

void Interprete::proceso()
{	
	metronomo.comprobarSonido();

	if (!notaActual.esValida()) {
		siguienteNota();
		return;
	}

	while (procesarNota()) {
		siguienteNota();
	}
}

void Interprete::fin()
{
	metronomo.parar();
}

#define MARGEN_ERROR_MS 2

bool Interprete::procesarNota()
{
    quint64 msActual = metronomo.getMilisegundosDesdeInicio();

	double milisegundosPorCompas = metronomo.getMilisegundosPorCompas();
	double milisegundosPorPulso = metronomo.getMilisegundosPorPulso();
	double milisegundosPorDivision = milisegundosPorPulso / notaActual.getDivisiones();

	quint64 msEvento =
		contadorCompas * milisegundosPorCompas +
		notaActual.getPulso() * milisegundosPorPulso +
		notaActual.getDivision() * milisegundosPorDivision;

	qint64 diferenciaMilisegundos;
	if (msEvento >= msActual) {
		diferenciaMilisegundos = msEvento - msActual;
	} else {
		diferenciaMilisegundos = - (double) (msActual - msEvento);
	}

	if (diferenciaMilisegundos > MARGEN_ERROR_MS) {
		// aun no le toca
		return false;
	}
	if (diferenciaMilisegundos < -MARGEN_ERROR_MS) {
		// se ha pasado su momento
		return true;
	}

	QString nombreNota = notaActual.getNombreNota();
	Entrenador::getInstancia()->marcarNotaEntrenamiento(msEvento, nombreNota);	
	return true;
}

void Interprete::primeraNota()
{
	if (compas.getNumeroNotas() == 0) {
		return;
	}

	contadorCompas = 0;
	contadorNotas = 0;
	notaActual = compas.getNota(0);
}

void Interprete::siguienteNota()
{
	int numeroNotas = compas.getNumeroNotas();
	if (numeroNotas == 0) {
		return;
	}
	
	if (++contadorNotas >= numeroNotas) {
		contadorNotas = 0;
		contadorCompas++;
	}
	notaActual = compas.getNota(contadorNotas);
}
